package org.onejava.core.manage;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.onejava.core.annotation.InterceptorInfo;
import org.onejava.core.bean.Allconfig;
import org.onejava.core.bean.InterceptorEntity;
import org.onejava.core.bean.MContext;
import org.onejava.core.tools.ObjectTools;
import org.onejava.core.tools.ScanTool;


public class InterceptorManage extends BaseManage{
	
	private static InterceptorManage manange;
	private HashMap<String,InterceptorEntity> entityMap;
    private  static Log log = LogFactory.getLog(InterceptorManage.class);  

	private InterceptorManage(){
		
	}
	
	public static InterceptorManage getManage(){
		if(null==manange){
			manange = new  InterceptorManage();
		}
		return manange;		
	}
 
	public void intiMap(String packagePath) throws Exception{
		if(null!=entityMap){
			return;
		}
		//扫描出所有Interceptor路径
		ScanTool sacntool = new ScanTool();
		List<String> list = sacntool.getAllClassName(Allconfig.truePath,packagePath);
		log.info("开始在路径<"+packagePath+">下扫描拦截器");
		entityMap = new HashMap<String, InterceptorEntity>();
		for(int i=0;i<list.size();i++){
			Object actionObj = ObjectTools.getTheObject(list.get(i));
			Method method=null;
			try {
				method = ObjectTools.getMethod(actionObj, Allconfig.defaultMethod, MContext.class);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				log.warn("扫描到的类<"+list.get(i)+">没有有效的<"+Allconfig.defaultMethod+">方法");
				continue;
			}
			Map interceptorInfoMap = getAnnotationInfo(method);
			String interceptorName = (String) interceptorInfoMap.get("name");
			if(null==interceptorName||"".equals(interceptorName)){
				log.warn("类<"+list.get(i)+">没有有效的注解信息,无法载入拦截器MAP中");
				continue;
			}
			InterceptorEntity ie = new InterceptorEntity(interceptorName,actionObj,method);
			
			//使用Ioc插件注入变量
			setBean(ie);
			Object obj =entityMap.put(interceptorName, ie);
			if(null!=obj){
				throw new Exception("拦截器:Name:"+interceptorName+">>>ClassPath:"+list.get(i)+"有重复 拦截器加载STOP");
			}
			log.info("拦截器:"+interceptorName+">>>ClassPath:"+list.get(i)+"载入成功");			
		}
	}
	
	public void doInterceptorChain(InterceptorEntity[] ieChain,MContext context) throws Exception{
		for(int i=0;i<ieChain.length;i++){
			doInterceptor(ieChain[i],context);
		}
	}
	public Object doInterceptor(InterceptorEntity ie,MContext context) throws Exception{
		Object result = null;
		try {
			result = ObjectTools.invokeObject(ie.getObj(), ie.getMethod(), context);
		} catch ( InvocationTargetException e) {
			// TODO Auto-generated catch block
			//log.error("发生了错误", e.getTargetException());
			throw new Exception(e.getTargetException());
		}
		//log.info("拦截器:<"+ie.getName()+">执行完毕");
		return result;
	}
	
	/**
	 * 获取拦截器链
	 * @param chain
	 * @return InterceptorChain
	 */
	public InterceptorEntity[] getInterceptorChain(String[] chain) throws Exception{
		if(null==chain||chain.length==0||null==entityMap){
			return null;
		}
		ArrayList<InterceptorEntity> list = new ArrayList<InterceptorEntity>();
		for(int i=0;i<chain.length;i++){
			if(null==chain[i]||"".equals(chain[i]))
				continue;
			InterceptorEntity ie =  entityMap.get(chain[i]);
			if(null==ie){
				log.warn("无法找到拦截器"+chain[i]);
				continue;
			}
			list.add(ie);	
		}
		if(list.size()<=0){
			return new InterceptorEntity[0] ;
		}
		return (InterceptorEntity[]) list.toArray(new InterceptorEntity[list.size()]);
		
	}
	/**
	 * 获取Interceptor的注解信息
	 * @param msa
	 * @return Map{befores，afters}
	 */
	private Map getAnnotationInfo(Method msa){
		InterceptorInfo annotation = msa.getAnnotation(InterceptorInfo.class);
		Map map  = new HashMap();
		if(null!=annotation){
			String name = annotation.name();
			map.put("name", name);
		}else{
			map.put("name", "");
		}
		return map;
	} 
}
